package com.richfit.cuba.web.client;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import com.richfit.cuba.modular.IScanService;
import com.richfit.cuba.modular.controller.BalanceInventoryYearDetailHandleService;
import com.richfit.cuba.modular.controller.SysRoleMenuHandleService;
import com.richfit.cuba.web.config.SpringContextHolder;
import com.richfit.cuba.web.config.util.AopTargetUtils;
import com.richfit.cuba.web.config.util.ScanTableUtils;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

/**
 * <pre>
 * 实际应用中，我们会有在项目服务启动的时候就去加载一些数据或做一些事情这样的需求。 
 * 为了解决这样的问题，spring Boot 为我们提供了一个方法，通过实现接口 CommandLineRunner 来实现。
 * Spring Boot应用程序在启动后，会遍历CommandLineRunner接口的实例并运行它们的run方法。
 * 也可以利用@Order注解（或者实现Order接口）来规定所有CommandLineRunner实例的运行顺序。
 * 参考网址：https://www.cnblogs.com/liuchuanfeng/p/6995391.html
 * 
 * </pre>
 * @author lanjf2000
 *
 */
@Component
public class InitThreadRun implements CommandLineRunner{
	
	private static final Log log = LogFactory.get();
	
	@Override
	public void run(String... args) throws Exception {
		Map<String, IScanService> maps = ScanTableUtils.getMaps();
		if(maps != null) {
    		for(Entry<String, IScanService> obj : maps.entrySet()) {
    			try {
    				String clazz = AopTargetUtils.getTarget(obj.getValue()).getClass().getName();
					System.out.println("key = "+obj.getKey()+" ; value = "+ clazz);
				} catch (Exception e) {
					e.printStackTrace();
				}
    			
    			
    			ThreadUtil.execute(new Runnable() {
					
					@Override
					public void run() {
						try {
							String classPath = null;
							IScanService clazz = obj.getValue();
							if(AopTargetUtils.isAopProxy(clazz)) {
								classPath = AopTargetUtils.getTarget(obj.getValue()).getClass().getName();
							}else {
								classPath = obj.getValue().getClass().getName();
							}
							log.info("classpath = "+classPath);
							
							invokMethod(classPath, "scanTable");
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});
    		}
		}
	}
	


    public void invokMethod(String classpath, String methodName){
        Object obj=null;
        Class<?> clazz=null;
        //通过Spring上下文去找 也有可能找不到
        try {
            obj= SpringContextHolder.getBean(StringUtils.uncapitalize(classpath.split("\\.")[classpath.split("\\.").length - 1]));
            if (obj == null){
                clazz = Class.forName(classpath);
                obj = clazz.newInstance();
            }else{
                clazz =obj.getClass();
            }
        }catch (Exception e){
        	log.error("classpath = [ "+classpath+" ], methodName = [ "+methodName+" ], bean : [ "+obj+" ] ");
            throw  new RuntimeException("ERROR:TaskUtils is Bean Create please check the classpath is`t right or not");
        }
        Method method=null;
        //获得方法名
        try {
            method = clazz.getMethod(methodName);
        } catch (NoSuchMethodException e) {
        	log.error("classpath = [ "+classpath+" ], methodName = [ "+methodName+" ], bean : [ "+obj+" ] ");
            throw  new RuntimeException("ERROR:TaskUtils is Bean the method Create please check the methodName is`t right or not");
        }
        //方法执行
        try {
            method.invoke(obj);
        } catch (Exception e) {
        	log.error("classpath = [ "+classpath+" ], methodName = [ "+methodName+" ], bean : [ "+obj+" ] ");
            throw  new RuntimeException("ERROR:TaskUtils is Bean the method execute please check the methodName is`t right or not");
        }

    }


}
